package com.ld.security.common.core.util;

import org.springframework.core.ResolvableType;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class GenericUtil {

	/**
	 * 获得制定类的泛型参数
	 * @param from 泛型子类
	 * @param to 泛型父类
	 * @param index 泛型参数下标
	 * @return
	 */
	public static Class<?> getGeneric(Class<?> from,Class<?> to,int... index){
		ResolvableType  rt=ResolvableType.forClass(from);
		return rt.as(to).getGeneric(index).resolve();  
	}
	
	//字段时泛型字段
	public static Class<?> getGeneric(Field field,int... index){
		//化为泛型集合
		ResolvableType resolvableType =ResolvableType.forField(field);
		return resolvableType.getGeneric(index).resolve();
	}
	
	public static Class<?> getFieldGeneric(Field field,int... index){
		ResolvableType  resolvableType = ResolvableType.forField(field);
		return resolvableType.getGeneric(index).resolve();
	}

	/**
	 * 从字段泛型中获取特定类型
	 * @param field
	 * @param target
	 * @return
	 */
	private static int[]  getFieldGeneric(Field field,Class target,LinkedList<Integer> list){

		Class clazz = null;
		int[] inds = new int[list.size() + 1];
		int ind = 0;
		for (Integer integer : list) {
			inds[ind]= integer;
		}

		for(int i = 0;;i++){
			inds[inds.length - 1] = i;
			clazz = getFieldGeneric(field,inds);
			if(clazz == null){
				break;
			}else if(target.isAssignableFrom(clazz)){
				return inds;
			} else{
				list.push(i);
				int[] bs = getFieldGeneric(field,target,list);
				if(bs != null){
					return bs;
				}
				list.pop();
			}

		}
		return null;
	}

	/**
	 * 从字段泛型中，获取指定泛型所在位置
	 * @param field
	 * @param target
	 * @return
	 */
  public static int[]  getFieldGeneric(Field field, Class target) {
	  LinkedList<Integer> list = 	new LinkedList<>();
	  return  getFieldGeneric(field,target,list);
  }

		public static Class<?> getMethodGeneric(Method method, int... index){
		ResolvableType  resolvableType = ResolvableType.forMethodReturnType(method);
		return resolvableType.getGeneric(index).resolve();
	}

	public  static void main(String[] args){

	}
}
